using Gateway.Common.Models;
using Gateway.IRepositories;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;

namespace Gateway.Dapper;

public static class DapperExtension
{
    private static List<QueryConnectionModel> _databases = new List<QueryConnectionModel>();
    private static int TotalWeight;

    /// <summary>
    /// 根据配置文件的字符串处理配置信息
    /// </summary>
    /// <param name="services"></param>
    /// <param name="connection"></param>
    public static void AddDapperConnection(this IServiceCollection services, string connection)
    {
        if (string.IsNullOrEmpty(connection))
        {
            throw new ArgumentNullException("配置的dapper为空");
        }

        try
        {
            var connections = JsonConvert.DeserializeObject<List<QueryConnectionModel>>(connection);
            AddDapperConnection(connections);
        }
        catch (Exception)
        {
            throw new ArgumentException("dapper 连接串格式错误，" + connection);
        }

        services.AddScoped<IQueryRepository, DapperRepository>();
    }

    /// <summary>
    /// 直接配置
    /// </summary>
    /// <param name="connections"></param>
    public static void AddDapperConnection(List<QueryConnectionModel> connections)
    {
        var weight = connections.Sum(p => p.Weight ?? 1);
        TotalWeight = (int)weight;
        _databases = connections;
    }

    /// <summary>
    /// 获取连接串
    /// </summary>
    /// <returns></returns>
    public static string GetConnectionString()
    {
        return GetRandomByGuid();
    }


    /// <summary>
    /// 使用Guid产生的种子生成真随机数
    /// </summary>
    private static string GetRandomByGuid()
    {
        Random random = new Random(GetRandomSeedbyGuid());
        var index = random.Next(0, TotalWeight);
        double cursor = 0;
        foreach (var item in _databases)
        {
            cursor += item.Weight ?? 1.0;
            if (cursor > index)
            {
                return item.Connection;
            }
        }

        return "";
    }

    /// <summary>
    /// 使用Guid生成种子
    /// </summary>
    /// <returns></returns>
    private static int GetRandomSeedbyGuid()
    {
        return Guid.NewGuid().GetHashCode();
    }
}